<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */


namespace app\madmin\service;


use app\index\model\OrderAgentProfit;
use app\madmin\model\AgentBillTemporary;
use app\madmin\model\Order;
use app\shop_admin\service\PaymentService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\HttpException;
use app\madmin\model\UserCoupon;
use app\madmin\model\Coupon;
use app\madmin\model\OrderCommodity;
use app\madmin\model\OrderAfter;
use app\madmin\model\AfterOrderCommodity;
use app\madmin\model\OrderFreight;
use think\facade\Db;

class OrderService
{
    /** 退款
     * @param int $oId
     * @return array
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     * @throws \think\db\exception\DbException
     */
    public function drawback(int $oId)
    {
        $find = Order::find($oId);
        if (!in_array($find['status'], [2])) throw new HttpException(HTTP_INVALID, '该订单状态不是待发货');
        if (in_array($find['after_status'], [1, 2])) throw new HttpException(HTTP_INVALID, '该订单为维权订单,不能退款!');
        $freight = OrderFreight::where('order_id', $oId)->value('freight');
        $money = bcsub($find['money'], ($find['discount'] + $find['discount_amount']), 2);
        $money += $freight;
        $pay = new PaymentService();
        $arr1 = false;
        if ($find->getData('pay_id') != 4) $arr1 = $pay->refund($oId, ['refund' => $money]);
        if ($arr1) {
            $this->return_coupon($oId);
            OrderCommodity::where('order_id', $oId)->update(['status' => 11, 'type' => 3]);
            $this->upOrderState($oId);
            AgentBillTemporary::where('order_id', $oId)->delete();
            OrderAgentProfit::where('order_id', $oId)->delete();
            return [HTTP_SUCCESS, '退款成功!'];
        } else
            return [HTTP_INVALID, '退款失败!'];
    }

    /** 退还优惠券 删除对应的分销数据
     * @param int $oId
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    private function return_coupon(int $oId)
    {
        $find = Order::find($oId);
        $user_coupon = UserCoupon::where('unified_order_no', $find['order_no'])->find();
        if (empty($user_coupon)) return;
        $coupon = Coupon::where('id', $user_coupon['coupon_id'])->find();
        $flag = true;
        $ids = OrderCommodity::where('order_id', $oId)->field('id')->select()->toArray();
        $id_arr = array_column($ids, 'id');
        $after_ids = OrderAfter::where('order_id', $oId)->field('id')->select()->toArray();
        $afters = array_column($after_ids, 'id');
        $ocids = AfterOrderCommodity::where('order_after_id', 'in', $afters)->field('ocid')->select()->toArray();
        $ocids_arr = array_column($ocids, 'ocid');
        $tally = count(array_diff($id_arr, $ocids_arr));
        //1-待支付 2-待发货 3-已发货 4-已完结 5-已评价   6-删除 7-部分发货 8-已收货 9-部分收货 10-维权中 11-维权完成 12-已关闭
        if (!in_array($find->getData('status'), [1, 2, 3, 7, 9]) || $tally > 1) {
            return;
        }
        if (!empty($coupon['limit_indate_begin']) && !empty($coupon['limit_indate_end'])) {
            if (time() < strtotime($coupon['limit_indate_begin']) || time() > strtotime($coupon['limit_indate_end'])) {
                $flag = false;
            }
        }
        if ($coupon['user_limit_type'] = 1) {
            $count = UserCoupon::where('user_id', $find['user_id'])
                ->where('coupon_id', $user_coupon['coupon_id'])
                ->count();
            if ($count >= $coupon['user_limit']) {
                $flag = false;
            }
        }
        if ($flag) {
            $user_coupon->unified_order_no = null;
            $user_coupon->status = 0;
            $user_coupon->save();
        }
    }

    /**
     * @param string $oId
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    private function upOrderState(string $oId)
    {
        //订单状态: 1-待支付 2-待发货 3-已发货 4-已完结 5-已评价 6-删除 7-部分发货 8-已收货 9-部分收货 10-维权中 11-维权完成 12-已关闭
        //订单-商品状态: 1-待支付 2-待发货 3-已发货 4-已完结 5-已评价 6-删除 7-已收货 8-维权中 9-已维权 10-维权驳回 11-已关闭
        $status_arr = Db::name('order_commodity')->where('order_id', $oId)->field('status')->group('status')->select()->toArray();
        $status = array_column($status_arr, 'status');
        if (count($status) > 1) {
            foreach ($status as $k => $v) {
                if ($v == 11) unset($status[$k]);
            }
            if (in_array(3, $status) && count($status) > 1 && !in_array(2, $status))
                $state = 7;
            elseif (in_array(2, $status) && count($status) > 1)
                $state = 2;
            elseif (in_array(7, $status) && count($status) > 1)
                $state = 9;
            elseif (count($status) == 1)
                $state = in_array(end($status), [7]) ? end($status) + 1 : end($status);

        } elseif (count($status) == 1) {
            switch ($status[0]) {
                case 1:
                    $state = 1;
                    break;
                case 2:
                    $state = 2;
                    break;
                case 3:
                    $state = 3;
                    break;
                case 4:
                    $state = 4;
                    break;
                case 5:
                    $state = 5;
                    break;
                case 6:
                    $state = 6;
                    break;
                case 7:
                    $state = 8;
                    break;
                case 11:
                    $state = 12;
                    break;
            }
        }
        $order = Order::find($oId);
        $order->status = $state;
        $order->save();
    }
}